{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from IPython.display import display, HTML"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "import markovify\n",
    "import spacy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## why display html?\n",
    "\n",
    "### View your text with nice linebreaks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [],
   "source": [
    "text = open(\"./frankenstein.txt\").read()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "gen = markovify.Text(text, state_size=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [],
   "source": [
    "sentences = [gen.make_sentence(tries=1000) for i in range(5)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_para = ' '.join(sentences)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'But I, the true murderer, felt the never-dying worm alive in my own heart I could give no account. The wet wood which I had consumed, I should guess that I had no means of extracting it. You accuse me of murder, and he endeavoured to prove to me the shifting colours of the landscape and the appearances of the sky. Know that, one by one, my friends were employed in their ordinary occupations. But I was not unacquainted with the language of the country ate, but I will disclose a secret.'"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_para"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "But I, the true murderer, felt the never-dying worm alive in my own heart I could give no account. The wet wood which I had consumed, I should guess that I had no means of extracting it. You accuse me of murder, and he endeavoured to prove to me the shifting colours of the landscape and the appearances of the sky. Know that, one by one, my friends were employed in their ordinary occupations. But I was not unacquainted with the language of the country ate, but I will disclose a secret.\n"
     ]
    }
   ],
   "source": [
    "print(new_para)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "But I, the true murderer, felt the never-dying worm alive in\n",
      "my own heart I could give no account. The wet wood which I\n",
      "had consumed, I should guess that I had no means of\n",
      "extracting it. You accuse me of murder, and he endeavoured\n",
      "to prove to me the shifting colours of the landscape and the\n",
      "appearances of the sky. Know that, one by one, my friends\n",
      "were employed in their ordinary occupations. But I was not\n",
      "unacquainted with the language of the country ate, but I\n",
      "will disclose a secret.\n"
     ]
    }
   ],
   "source": [
    "from textwrap import fill\n",
    "print(fill(new_para, 60))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "But I, the true murderer, felt the never-dying worm alive in my own heart I could give no account. The wet wood which I had consumed, I should guess that I had no means of extracting it. You accuse me of murder, and he endeavoured to prove to me the shifting colours of the landscape and the appearances of the sky. Know that, one by one, my friends were employed in their ordinary occupations. But I was not unacquainted with the language of the country ate, but I will disclose a secret."
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(HTML(new_para))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### embed stuff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/jOBRLH9O2i4\" frameborder=\"0\"></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(HTML('<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/jOBRLH9O2i4\" frameborder=\"0\"></iframe>'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### add formatting\n",
    "\n",
    "Tutorials from Allison:\n",
    "\n",
    "* [Basic HTML](http://hypertext.decontextualize.com/elementary/)\n",
    "* [Simple CSS](http://hypertext.decontextualize.com/css-with-style/)\n",
    "* [Positioning and layout](http://hypertext.decontextualize.com/your-position-is-clear/)\n",
    "\n",
    "General refs:\n",
    "\n",
    "* [Learn Layout](http://learnlayout.com/)\n",
    "* [MDN on HTML](https://developer.mozilla.org/en-US/docs/Web/HTML)\n",
    "* [MDN on CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<p>But I, the true murderer, felt the never-dying worm alive in my own heart I could give no account. The wet wood which I had consumed, I should guess that I had no means of extracting it. You accuse me of murder, and he endeavoured to prove to me the shifting colours of the landscape and the appearances of the sky. Know that, one by one, my friends were employed in their ordinary occupations. But I was not unacquainted with the language of the country ate, but I will disclose a secret.</p>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(HTML(\"<p>\" + new_para + \"</p>\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<p>I thought of the occurrences of the day was spent in observing my friends. Shall I not then expire! I trembled and my heart often sickened at the work of your own hands.</p><p>Sometimes I sat with my eyes fixed on the consummation of his happiness. My rage is unspeakable when I reflect that you are sincere. Before this I was not even of the same species and have the same defects.</p><p>My companion must be of the same nature as man. But it refreshed me and filled me with an insatiable thirst for vengeance. I had turned loose into the world for my destruction.</p>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "new_text = \"\"\n",
    "for i in range(3):\n",
    "    sentences = [gen.make_short_sentence(80, tries=1000) for i in range(3)]\n",
    "    new_para = \" \".join(sentences)\n",
    "    new_text += \"<p>\" + new_para + \"</p>\"\n",
    "display(HTML(new_text))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<p style='width: 40em'>Between two and three in the morning when I entered my father's house. I ordered it to be composed of wood. Ruined castles hanging on the precipices of an inaccessible mountain.</p><p style='width: 40em'>But I did not speak. I pressed on, and in two months I began to reflect on all that had passed. As I still pursued my journey to the sea of ice.</p><p style='width: 40em'>Sometimes I thought that as I could spare. One day, when my father entered the chamber. Then the appearance of my father is in the greatest danger.</p>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "new_text = \"\"\n",
    "for i in range(3):\n",
    "    sentences = [gen.make_short_sentence(80, tries=1000) for i in range(3)]\n",
    "    new_para = \" \".join(sentences)\n",
    "    new_text += \"<p style='width: 40em'>\" + new_para + \"</p>\"\n",
    "display(HTML(new_text))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<p style='width: 40em; font-family: Georgia, serif;'>Do your duty towards me, and I began to study them with diligence. For a moment my father entered the chamber. Agatha, the ever-gentle Agatha, kissed the hands of Elizabeth and myself.</p><p style='width: 40em; font-family: Georgia, serif;'>Fortunately I had money with me and for me. I leave a sad and bitter world; and if you obey me in this state of degradation. I feared to wander from the sight of which was sickening to me.</p><p style='width: 40em; font-family: Georgia, serif;'>Chapter 5 It was on a level with your own. She thanked him in the most melancholy reflections. It was situated against the back of the cottage it was tolerably warm.</p>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "new_text = \"\"\n",
    "for i in range(3):\n",
    "    sentences = [gen.make_short_sentence(80, tries=1000) for i in range(3)]\n",
    "    new_para = \" \".join(sentences)\n",
    "    new_text += \"<p style='width: 40em; font-family: Georgia, serif;'>\" + new_para + \"</p>\"\n",
    "display(HTML(new_text))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### highlighting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [],
   "source": [
    "nlp = spacy.load('en_core_web_md')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "The old <span style='color: blue;'>man</span> <span style='color: red;'>appeared</span> enraptured and <span style='color: red;'>said</span> some <span style='color: blue;'>words</span> which Agatha <span style='color: red;'>endeavoured</span> to <span style='color: red;'>explain</span> to me that I <span style='color: red;'>should</span> <span style='color: red;'>make</span> <span style='color: blue;'>use</span> of the same <span style='color: blue;'>species</span> and <span style='color: red;'>have</span> the same <span style='color: blue;'>defects</span>."
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "gen_text = gen.make_sentence(tries=1000)\n",
    "output = \"\"\n",
    "for word in nlp(gen_text):\n",
    "    if word.pos_ == 'NOUN':\n",
    "        output += \"<span style='color: blue;'>\" + word.text + \"</span>\"\n",
    "    elif word.pos_ == 'VERB':\n",
    "        output += \"<span style='color: red;'>\" + word.text + \"</span>\"\n",
    "    else:\n",
    "        output += word.text\n",
    "    output += word.whitespace_\n",
    "display(HTML(output))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## page layouts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [],
   "source": [
    "tmpl = \"\"\"\n",
    "<!doctype HTML>\n",
    "<html lang='en'>\n",
    "<head>\n",
    "    <meta charset=\"utf-8\">\n",
    "    <style type=\"text/css\">\n",
    "        * { box-sizing: border-box; }\n",
    "        html { width: 8.5in; height: 11in; }\n",
    "        body {\n",
    "            height: 100%%;\n",
    "            width: 100%%;\n",
    "            margin: 0;\n",
    "            border: 1px grey dotted; /* comment out this line to remove border */\n",
    "        }\n",
    "    </style>\n",
    "</head>\n",
    "<body>\n",
    "%s\n",
    "</body>\n",
    "</html>\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "<!doctype HTML>\n",
      "<html lang='en'>\n",
      "<head>\n",
      "    <meta charset=\"utf-8\">\n",
      "    <style type=\"text/css\">\n",
      "        * { box-sizing: border-box; }\n",
      "        html { width: 8.5in; height: 11in; }\n",
      "        body {\n",
      "            height: 100%;\n",
      "            width: 100%;\n",
      "            margin: 0;\n",
      "            border: 1px grey dotted;\n",
      "        }\n",
      "    </style>\n",
      "</head>\n",
      "<body>\n",
      "hello\n",
      "</body>\n",
      "</html>\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(tmpl % \"hello\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(\"output-test.html\", \"w\") as fh:\n",
    "    fh.write(tmpl % gen.make_sentence(tries=1000))\n",
    "!open output-test.html"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_text = \"\"\n",
    "for i in range(7):\n",
    "    sentences = [gen.make_short_sentence(80, tries=1000) for i in range(3)]\n",
    "    new_para = \" \".join(sentences)\n",
    "    new_text += \"<p>\" + new_para + \"</p>\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [],
   "source": [
    "output = \"<div style='width: 25em; font-size: 16pt; line-height: 1.2em; margin: 0 auto;'>\" + \\\n",
    "    \"<h1>My New Frankenstein</h1>\" + \\\n",
    "    new_text + \\\n",
    "    \"</div>\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(\"output-test.html\", \"w\") as fh:\n",
    "    fh.write(tmpl % output)\n",
    "!open output-test.html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Concrete compositions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "66.11020517230256"
      ]
     },
     "execution_count": 117,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "random.uniform(0, 100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "top: 15px; left: 5px;\n",
      "top: 4.56in; left: 1.23in;\n"
     ]
    }
   ],
   "source": [
    "def topleft(x, y, unit='in'):\n",
    "    left_str = \"left: \" + str(x) + unit + \";\"\n",
    "    top_str = \"top: \" + str(y) + unit + \";\"\n",
    "    return top_str + \" \" + left_str\n",
    "print(topleft(5, 15, 'px'))\n",
    "print(topleft(1.23, 4.56))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [],
   "source": [
    "frank_words = random.sample(text.split(), 500)\n",
    "output = \"\"\n",
    "for word in frank_words:\n",
    "    pos = topleft(random.uniform(0.5, 7.5), random.uniform(0.5, 10.5))\n",
    "    output += \"<div style='position: absolute; \" + pos + \"'>\" + word + \"</div>\"\n",
    "with open(\"output-test.html\", \"w\") as fh:\n",
    "    fh.write(tmpl % output)\n",
    "!open output-test.html"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [],
   "source": [
    "frost_words = open(\"./frost.txt\").read().split()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1.7320508075688774, 0.9999999999999999)"
      ]
     },
     "execution_count": 132,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import math\n",
    "def polar2xy(r, theta):\n",
    "    x = r * math.cos(theta)\n",
    "    y = r * math.sin(theta)\n",
    "    return (x, y)\n",
    "polar2xy(2, math.pi / 6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "metadata": {},
   "outputs": [],
   "source": [
    "output = \"\"\n",
    "for i, word in enumerate(frost_words):\n",
    "    xpos, ypos = polar2xy(0.5 + (i*0.025), i * 0.25)\n",
    "    output += \"<div style='position: absolute; \" + \\\n",
    "        topleft(xpos + 4.25, ypos + 5.5) + \"'>\" + word + \"</div>\"\n",
    "with open(\"output-test.html\", \"w\") as fh:\n",
    "    fh.write(tmpl % output)\n",
    "!open output-test.html"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
